/*
 * Copyright 2007-2010 Jeremy Brown.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author <a href="http://jeremy-brown.com">Jeremy Brown</a>
 */

package groovy.prefuse.factory

import prefuse.Display
import prefuse.Visualization
import prefuse.data.Table
import prefuse.render.RendererFactory
import prefuse.render.DefaultRendererFactory


public class VisualizationFactory extends AbstractFactory
{
	boolean isLeaf()
	{
		return false
	}
    
    public Object newInstance(FactoryBuilderSupport builder, Object name, Object value, Map attributes) throws InstantiationException, IllegalAccessException
	{
		def rendererFactory = attributes.remove("rendererFactory")
		def visualization
		
		//It's annoying to have to keep specifying group:"my_group" for so many of your Actions, Layouts, etc. So you can specify pfVisualization(defaultGroup:"my_group") and it will store the default for you. You can still override the default by specifying, for example, pfAxisLayout(group:"some_other_group").
		builder.setPrefuseDefaultGroup(attributes.remove("defaultGroup")) //Store the defaultGroup as a property in PrefuseBuilder for later use by AssignmentFactory, LayoutFactory, etc.
		
		//Visualization.setInteractive() doesn't work until after the Table, Tree, or Graph with the nodes/edges has been defined. So save this node until the onNodeCompleted stage.
		builder.context.interactive = attributes.remove("interactive")
		
		if(value instanceof Visualization)
		{
			//If a Visualization object is passed in as the value, use it
			visualization = value
			if(rendererFactory && rendererFactory instanceof RendererFactory)
			{
				visualization.setRendererFactory(rendererFactory)
			}
		}
		else
		{
			//Otherwise we create a new Visualization
			visualization = new Visualization()
			if(rendererFactory && rendererFactory instanceof RendererFactory)
			{
				visualization.setRendererFactory(rendererFactory)
			}
			else
			{
				visualization.setRendererFactory(new DefaultRendererFactory())
			}
		}
		return visualization
    }
	
	
	public void onNodeCompleted(FactoryBuilderSupport builder, Object parent, Object child) 
	{
		addNodeToParent(builder, parent, child)

		//setInteractive only works after the Table/Graph/Tree inside the Visulization has been defined, so we do it here in the onNodeCompleted method
		if(builder.context.interactive)
		{
			def interactive = builder.context.interactive
			//List of Lists?
			if(interactive instanceof List && interactive[0] instanceof List)
			{
				interactive.each{list->
					child.setInteractive(*list)
				}
			}
			//List of values
			else
			{
				child.setInteractive(*interactive)
			}
		}
    }
	
	public void addNodeToParent(FactoryBuilderSupport builder, Object parent, Object child)
	{
		if(parent instanceof Display)
		{
			parent.setVisualization(child)
		}
	}
}
